home *** CD-ROM | disk | FTP | other *** search
- page 55,132
- Title Copyright and Serial Number Module
- Subttl SERNO.ASM
- ;-----------------------------------------------------------------------
- ; Copyright and Serial Number Module
- ;-----------------------------------------------------------------------
- ;
- ; This module implements a protected embedded copyright message,
- ; serial number, and version number scheme. Its purpose is as
- ; described below.
- ;
- ; Copyright Message
- ; -----------------
- ;
- ; A standard copyright message is included in this module. This
- ; copyright message is a standard C null-terminated string that is
- ; included in the TEXT segment (code) rather than in the BSS segment
- ; with all other initialized variables.
- ;
- ; The copyright message is intended to be a standard copyright used
- ; with all distributed software. It may be changed provided that the
- ; software that this module is used with is relinked, and provided
- ; that the SETVER utility is reassembled/recompiled with the new
- ; module.
- ;
- ; The copyright message, as it is assembled with this module, is
- ; assembled such that an XOR checksum of the copyright message
- ; characters will be nonzero. This signals that one of two possible
- ; problems exist: (1) the copyright message has been tampered with
- ; or removed, or (2) the program file has not yet been serialized.
- ;
- ; This module provides a function called GetCopyright() that returns
- ; a FAR pointer to the copyright message. This pointer will be NULL
- ; if either of the above two conditions exists, and the caller of
- ; GetCopyright() then has the option of terminating the program
- ; because of an invalid copyright. The pointer must be FAR because
- ; C will normally expect to find it in the data segment addressed
- ; via the DS register.
- ;
- ; If GetCopyright() returns a nonzero FAR pointer, then the copyright
- ; message and the serial and version numbers are intact, and the caller
- ; may elect to display the copyright message on the screen. Note that
- ; the GetCopyright() function is the ONLY function that verifies the
- ; XOR checksum, and should be called to verify that the program file
- ; has not been modified and that the serial and version numbers are
- ; valid even if the copyright message is not to be displayed.
- ;
- ; Serial Number
- ; -------------
- ;
- ; Provision is made for a ten-digit numeric serial number encoded as a
- ; long integer. The function GetSerialNumber() returns this serial
- ; number, which may be displayed on the screen or used programmatically
- ; to make decisions based on the serial number.
- ;
- ; Version Number
- ; --------------
- ;
- ; Provision is made for a five-digit numeric version number encoded as
- ; an unsigned integer. The function GetVersionNumber() returns this
- ; version number, which may be displayed on the screen or used
- ; programmatically to make decisions based on the version number.
- ;
- ; Serialization
- ; -------------
- ;
- ; This module assumes that a separate program will be used to serialize
- ; the program. This serialization program (SETVER) performs three
- ; functions:
- ;
- ; (1) It inserts the proper XOR checksum on the copyright message,
- ; which signals the program at run-time that the copyright message
- ; has not been tampered with.
- ;
- ; (2) It inserts the desired serial number, which is NOT stored in
- ; standard LSB...MSB form. If the serial number is displayed on
- ; the screen, a fairly competent hacker, finding that the serial
- ; number is not encoded literally (in ASCII), will assume that
- ; it is stored in binary and may search for the binary sequence.
- ; In this way the serial number may be changed. To defeat this,
- ; the second and fourth bytes of the serial number are swapped,
- ; which will not convert to anything even close to the proper
- ; serial number.
- ;
- ; (3) It inserts the desired version number, which is stored in
- ; standard LSB...MSB integer form.
- ;
- ; (4) A standard checksum will be performed on the copyright and
- ; serial/version number areas, and a special checksum byte
- ; adjusted so that the .EXE file checksum remains correct. If
- ; this is not done, the DOS EXEC loader may reject the .EXE file.
- ;
- ; Because the DOS EXEC loader performs all segment fixups, the
- ; serialization program must search for a key field. The copyright
- ; message serves as the search key. This same module is used by the
- ; serialization program, so there is no possibility of invalidating
- ; the key.
- ;
- ; Therefore, if either the serial number or copyright message are
- ; changed, DOS may refuse to load the program. If someone familiar
- ; enough with the .EXE file format knows about the .EXE checksum
- ; and corrects it, the XOR checksum will still prevent the program
- ; from operating if this is desired by the caller of GetCoptright().
- ; Since the checksum scheme is unknown, it will be difficult to install
- ; the proper XOR checksum to defeat the protection.
- ;
- ; While these measures may not prevent a sophisicated and determined
- ; individual from modifying either the copyright or the serial number,
- ; it should provide protection from most users.
- ;
- ; Assembly
- ; --------
- ;
- ; This module must be assembled with the Microsoft Macro Assmbler
- ; (MASM) Version 5.1 or later. The MASM command line is as follows:
- ;
- ; MASM /Ml /DMODEL=model serno;
- ;
- ; where 'model' is one of SMALL, MEDIUM, COMPACT, or LARGE. The
- ; assembled module is intended to be linked with a C program compiled
- ; with Microsoft C V5.1 or later.
- ;
- ;-----------------------------------------------------------------------
-
- % .MODEL MODEL,C
-
- page
- ;-----------------------------------------------------------------------
- ; Serial Number and Checksum Structure
- ;-----------------------------------------------------------------------
-
- sn_blk struc
- SN_Data dd 0 ;serial number, bytes 2 and 4 swapped
- VN_Data dw 0 ;version number
- SN_Cksm db 0 ;copyright and serial number checksum
- EXE_Cksm db 0 ;DOS .EXE file checksum correction
- sn_blk ends
-
- ;-----------------------------------------------------------------------
- ; Code Segment Definition
- ;-----------------------------------------------------------------------
-
- .CODE
-
- page
- ;-----------------------------------------------------------------------
- ; Verify and Return Pointer To Copyright Message
- ;-----------------------------------------------------------------------
- ;
- ; This function will return a FAR pointer to the copyright message.
- ; A far pointer is used because the copyright message is not in
- ; the standard C data segment; rather, it is in the code segment.
- ; This function will return a NULL pointer if the copyright message
- ; or serial number have not been initialized by the serialization
- ; utility or if either has been tampered with.
- ;
- ; This function is declared and used as follows.
- ;
- ; /* function prototype */
- ;
- ; char far *GetCopyright (void);
- ;
- ; /* example usage */
- ;
- ; char far *p;
- ;
- ; if ((p = GetCopyright ()) == (char far *) NULL)
- ; {
- ; /* print error and/or abort execution */
- ; ......
- ; }
- ; else
- ; printf ("%Fs", p);
- ;
- ; The 'F' in the printf() format specification tells printf() that
- ; 'p' is a far pointer.
- ;
- ;-----------------------------------------------------------------------
-
- GetCopyright proc
- mov bx,offset @code:_CopyrightMsg ;point to copyright message
- push cs ;** stack far pointer to message
- push bx ;*
- if @CodeSize ;if large code model
- push cs ;stack segment first
- endif
- call near ptr _CPSUM ;calculate the XOR checksum
- add sp,4 ;clear stack
- mov dx,cs ;get segment address to DX
- cmp al,byte ptr cs:sn.SN_Cksm ;valid checksum?
- mov ax,bx ;get offset to AX
- jz short GetCopyright0 ;yes, return segment and offset
- sub ax,ax ;** no, return null pointer
- mov dx,ax ;*
- GetCopyright0:
- ret
- GetCopyright endp
-
- page
- ;-----------------------------------------------------------------------
- ; Return Pointer To Copyright Message
- ;-----------------------------------------------------------------------
- ;
- ; This function will return a FAR pointer to the copyright message.
- ; A far pointer is used because the copyright message is not in
- ; the standard C data segment; rather, it is in the code segment.
- ; This function will always return a valid far pointer to the
- ; copyright message, and is intended to be used by the serialization
- ; program to locate the copyright message in the target file.
- ;
- ; This function is declared and used as follows.
- ;
- ; /* function prototype */
- ;
- ; char far *_CPPTR (void);
- ;
- ; /* example usage */
- ;
- ; char far *p;
- ;
- ; p = _CPPTR ();
- ;
- ;-----------------------------------------------------------------------
-
- _CPPTR proc
- mov dx,cs ;** return far pointer to copyright
- mov ax,offset @code:_CopyrightMsg ;*
- ret ;and return
- _CPPTR endp
-
- page
- ;-----------------------------------------------------------------------
- ; Return Serial Number
- ;-----------------------------------------------------------------------
- ;
- ; This function will return the program serial number as a standard
- ; C long integer value. This value may be printed using printf().
- ;
- ; The function GetCopyright() should always be called first to
- ; determine if the serial number is valid.
- ;
- ; The function is declared and used as follows.
- ;
- ; /* function prototype */
- ;
- ; long cdecl GetSerialNumber (void);
- ;
- ; /* example usage */
- ;
- ; printf ("Serial Number %lu", GetSerialNumber ());
- ;
- ;-----------------------------------------------------------------------
-
- GetSerialNumber proc
- mov ax,word ptr cs:sn.SN_Data ;** get serial number to DX:AX
- mov dx,word ptr cs:sn.SN_Data+2 ;*
- xchg ah,dh ;swap second and fourth bytes
- ret ;and return
- GetSerialNumber endp
-
- page
- ;-----------------------------------------------------------------------
- ; Return Version Number
- ;-----------------------------------------------------------------------
- ;
- ; This function will return the program version number as a standard
- ; C unsigned integer value. This value may be printed using printf().
- ;
- ; The function GetCopyright() should always be called first to
- ; determine if the version number is valid.
- ;
- ; The function is declared and used as follows.
- ;
- ; /* function prototype */
- ;
- ; unsigned int cdecl GetVersionNumber (void);
- ;
- ; /* example usage */
- ;
- ; printf ("Version Number %u", GetVersionNumber ());
- ;
- ;-----------------------------------------------------------------------
-
- GetVersionNumber proc
- mov ax,word ptr cs:sn.VN_Data ;get version number to AX
- ret ;and return
- GetVersionNumber endp
-
- page
- ;-----------------------------------------------------------------------
- ; Calculate Copyright XOR Checksum
- ;-----------------------------------------------------------------------
- ;
- ; This function will calculate the XOR checksum on the copyright
- ; message and return it. For copyright and checksum verification,
- ; this value should be compared to that stored in SN_Cksm; for
- ; serialization, it should be stored at the copyright message
- ; plus the offset stored in SN_Cksm.
- ;
- ; Synopsis:
- ;
- ; sum = _CPSUM (ptr);
- ;
- ; int sum; XOR checksum of copyright and
- ; serial number, rotated left once
- ; char far *ptr; far pointer to copyright message
- ;
- ;-----------------------------------------------------------------------
-
- _CPSUM proc uses ds si, address:far ptr
- lds si,address ;get address of string
- sub ah,ah ;clear XOR checksum
-
- ; perform checksum on copyright string
-
- _CPSUM0:
- lodsb ;get byte
- xor ah,al ;accumulate into checksum
- or al,al ;at end of copyright string?
- jnz _CPSUM0 ;no, loop
-
- ; perform checksum on serial number
-
- mov cx,SN_Cksm ;get offset to checksum byte
- _CPSUM1:
- lodsb ;get byte
- xor ah,al ;accumulate into checksum
- loop _CPSUM1 ;loop up to checksum byte
- mov al,ah ;** get checksum to AX
- mov ah,cl ;*
- ret ;and return it
- _CPSUM endp
-
- page
- ;-----------------------------------------------------------------------
- ; Copyright Message and Serial Number Data Area
- ;-----------------------------------------------------------------------
-
- _CopyrightMsg label byte ;copyright message
- db "Copyright (c) 1988 "
- db "Quid Pro Quo Software. "
- db "All rights reserved.",0
- sn sn_blk <> ;serial number block
-
- end
-